/**
 * OCR 问题诊断脚本
 * 用于快速检测和解决常见的OCR问题
 */

const { spawn } = require('child_process');
const path = require('path');
const fs = require('fs');

class OCRDiagnostic {
    constructor() {
        this.pluginDir = __dirname;
        this.pythonExe = path.join(this.pluginDir, 'python', 'python.exe');
        this.ocrScript = path.join(this.pluginDir, 'ocr_infer.py');
    }

    async log(message) {
        const timestamp = new Date().toISOString();
        console.log(`[${timestamp}] ${message}`);
    }

    async checkFile(filePath, description) {
        const exists = fs.existsSync(filePath);
        await this.log(`${description}: ${exists ? '✅ 存在' : '❌ 不存在'} - ${filePath}`);
        return exists;
    }

    async runCommand(command, args, options = {}) {
        return new Promise((resolve) => {
            const process = spawn(command, args, {
                stdio: ['pipe', 'pipe', 'pipe'],
                ...options
            });

            let stdout = '';
            let stderr = '';

            process.stdout.on('data', (data) => {
                stdout += data.toString();
            });

            process.stderr.on('data', (data) => {
                stderr += data.toString();
            });

            process.on('close', (code) => {
                resolve({ code, stdout, stderr });
            });

            process.on('error', (error) => {
                resolve({ code: -1, error: error.message, stdout: '', stderr: '' });
            });
        });
    }

    async testPythonEnvironment() {
        await this.log('\n🔍 检查Python环境...');
        
        // 检查文件存在性
        const pythonExists = await this.checkFile(this.pythonExe, 'Python可执行文件');
        const scriptExists = await this.checkFile(this.ocrScript, 'OCR脚本');
        
        if (!pythonExists || !scriptExists) {
            return false;
        }

        // 测试Python基本功能
        await this.log('\n🧪 测试Python基本功能...');
        const basicTest = await this.runCommand(this.pythonExe, ['-c', 'print("Python工作正常")']);
        await this.log(`Python基本测试: 退出代码=${basicTest.code}, 输出="${basicTest.stdout.trim()}"`);

        // 测试依赖包
        await this.log('\n📦 检查依赖包...');
        const packages = ['paddleocr', 'paddlepaddle', 'numpy'];
        
        for (const pkg of packages) {
            const result = await this.runCommand(this.pythonExe, ['-c', `import ${pkg}; print("${pkg} OK")`]);
            const status = result.code === 0 ? '✅' : '❌';
            await this.log(`${status} ${pkg}: ${result.code === 0 ? 'OK' : result.stderr || '导入失败'}`);
        }

        return basicTest.code === 0;
    }

    async testOCRScript() {
        await this.log('\n🖼️ 测试OCR脚本...');
        
        // 创建一个简单的测试文件路径（即使文件不存在，我们也能测试脚本的参数处理）
        const testImagePath = path.join(this.pluginDir, 'test_image_not_exist.jpg');
        
        const result = await this.runCommand(this.pythonExe, [this.ocrScript, testImagePath, 'ch'], {
            timeout: 30000
        });

        await this.log(`OCR脚本测试结果:`);
        await this.log(`  退出代码: ${result.code}`);
        await this.log(`  标准输出长度: ${result.stdout.length} 字符`);
        await this.log(`  标准错误长度: ${result.stderr.length} 字符`);
        
        if (result.stdout) {
            await this.log(`  标准输出预览: ${result.stdout.substring(0, 200)}...`);
        }
        
        if (result.stderr) {
            await this.log(`  标准错误预览: ${result.stderr.substring(0, 200)}...`);
        }

        // 检查是否是预期的"文件不存在"错误（退出代码4）
        if (result.code === 4) {
            await this.log('✅ OCR脚本工作正常（正确检测到文件不存在）');
            return true;
        } else {
            await this.log(`⚠️ OCR脚本返回意外退出代码: ${result.code}`);
            return false;
        }
    }

    async analyzeErrors(result) {
        await this.log('\n🔍 错误分析...');
        
        const { code, stdout, stderr } = result;
        
        // 分析常见错误模式
        const errorPatterns = [
            {
                pattern: /Unknown argument.*show_log/i,
                solution: 'PaddleOCR版本过旧，不支持show_log参数。建议升级PaddleOCR或使用参数兼容性修复。'
            },
            {
                pattern: /No module named.*paddleocr/i,
                solution: 'PaddleOCR未安装。运行: python.exe -m pip install paddleocr paddlepaddle'
            },
            {
                pattern: /encoding.*error/i,
                solution: '编码问题。检查系统编码设置或图片文件路径是否包含特殊字符。'
            },
            {
                pattern: /Creating model.*UVDoc/i,
                solution: 'PaddleOCR正在下载模型文件，这是正常现象。首次使用需要下载，请耐心等待。'
            },
            {
                pattern: /信息.*无法找到文件/,
                solution: 'PaddleOCR模型文件下载或初始化问题。检查网络连接，或删除.paddlex缓存重试。'
            }
        ];

        let foundSolution = false;
        const allText = stdout + stderr;
        
        for (const { pattern, solution } of errorPatterns) {
            if (pattern.test(allText)) {
                await this.log(`💡 发现问题: ${solution}`);
                foundSolution = true;
            }
        }

        if (!foundSolution && code !== 0) {
            await this.log('❓ 未识别的错误模式，请检查完整日志或联系支持。');
        }
    }

    async runFullDiagnostic() {
        await this.log('🚀 开始OCR诊断...');
        await this.log(`插件目录: ${this.pluginDir}`);
        
        // 检查环境
        const envOk = await this.testPythonEnvironment();
        
        if (envOk) {
            // 测试脚本
            const scriptOk = await this.testOCRScript();
            
            if (scriptOk) {
                await this.log('\n✅ 诊断完成：OCR环境正常，可以正常使用。');
            } else {
                await this.log('\n⚠️ 诊断完成：OCR脚本存在问题，需要进一步检查。');
            }
        } else {
            await this.log('\n❌ 诊断完成：Python环境不完整，需要重新安装。');
        }

        await this.log('\n📋 建议的解决步骤:');
        await this.log('1. 确保网络连接正常（首次使用需要下载模型）');
        await this.log('2. 如果是参数错误，脚本已包含兼容性处理');
        await this.log('3. 如果是编码问题，检查图片路径是否包含中文或特殊字符');
        await this.log('4. 如果问题持续，可以删除.paddlex目录重新下载模型');
    }
}

// 如果直接运行此脚本
if (require.main === module) {
    const diagnostic = new OCRDiagnostic();
    diagnostic.runFullDiagnostic().catch(console.error);
}

module.exports = OCRDiagnostic;